/*
 * @Author: Roscoe
 * @Date:   2016-08-04 21:50:35
 * @Last Modified by:   Roscoe
 * @Last Modified time: 2016-09-27 15:16:19
 */

'use strict';
const queue = [];

/**
 * usage:
 * 
 * staticJsonp({
 *  url,
 *  cbName,
 *  cbFn,
 *  cache
 * }).then(successHandler).catch(failedHandler);
 * 
 * request url like this: ${url}?${cbName}=${cbFn}
 * if query param exist : ${url}?${cbName}=${cbFn}
 * if set cache = false :${url}?${cbname}=${cbFn}&__${someRandomNumber}=${someOtherRandomNumber}
 */
function staticJsonp({
  url,
  cbName = 'callback',
  cbFn = 'callback',
  cache = true
}) {
  return new Promise((resolve, reject) => {
    //如果已经有进行中的
    let task = ({
      url,
      cbName,
      cbFn,
      cache,
      resolve,
      reject
    });

    if (window[cbFn] || queue.includes(item => item.cbFn == cbFn)) {
      queue.push(task);
    } else {
      run(task);
    }
  });
}

function next(cbFn) {
  let task;
  let idx = queue.findIndex(item => item.cbFn == cbFn);
  if (idx !== -1) {
    task = queue.splice(idx, 1)[0];
  }
  if (task) {
    run(task);
  }
}

function run(task) {
  jsonp(task).then(data => {
    task.resolve(data);
    next(task.cbFn);
  }).catch(e => {
    task.reject(e);
    next(task.cbFn);
  });
}

function jsonp({ url, cbName, cbFn, cache }) {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script');
    let res;
    window[cbFn] = (data) => {
      res = data;
    };
    script.onload = () => {
      resolve(res);
      script.parentNode && script.parentNode.removeChild(script);
      window[cbFn] = undefined;
    };
    script.onerror = () => {
      reject('[request failed]');
      window[cbFn] = undefined;
    };

    //如果已经有search，则追加参数
    let paramSeperator = '?';
    if (url.indexOf('?') > -1) {
      paramSeperator = '&'
    }

    //如果不开cache，再后面拼个随机串
    let random = ``;
    if (!cache) {
      random = `&__${Math.ceil(Math.random()*10e6)}=${new Date().getTime()}`;
    }

    script.src = `${url}${paramSeperator}${cbName}=${cbFn}${random}`;
    document.body.appendChild(script);
  });
}
export default staticJsonp;
